package com.app.baselibrary.utils

import android.content.Context
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkRequest
import android.os.Build
import androidx.annotation.CheckResult
import androidx.annotation.NonNull
import androidx.annotation.RequiresApi
import com.app.baselibrary.ktx.APPLICATION
import com.app.baselibrary.ktx.runUI

/**
 * 网络状态工具类
 */
class NetworkUtil private constructor(){

    companion object {

        private val networkUtil by lazy { NetworkUtil() }

        private val connectivityManager by lazy {
           APPLICATION.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager?
        }

        internal val networkListenerList by lazy { ArrayList<NetworkListener>() }

        /**
         * 注册网络监听
         */
        @JvmStatic
        fun init(){
            if (Build.VERSION.SDK_INT >=Build.VERSION_CODES.LOLLIPOP){
                connectivityManager?.apply {
                    val request = NetworkRequest.Builder().build()
                    registerNetworkCallback(request, CustomNetworkCallback())
                }
            }
            else{
                val request = connectivityManager?.activeNetworkInfo
            }
        }

        /**
         * 当前网络是否可用
         */
        @CheckResult
        @JvmStatic
        fun active(): Boolean {
            return networkUtil.isActive()
        }

        /**
         * 当前是否是wifi
         */
        @CheckResult
        @JvmStatic
        fun wifi(): Boolean {
            return networkUtil.isWifi()
        }

        /**
         * 注册一个网络监听
         */
        @JvmStatic
        fun registerNetworkListener(@NonNull listener: NetworkListener){
            synchronized(networkListenerList){
                if (!networkListenerList.contains(listener)){
                    networkListenerList.add(listener)
                }
            }
        }


        /**
         * 移除一个注册监听
         */
        @JvmStatic
        fun unRegisterNetworkListener(@NonNull listener: NetworkListener){
            synchronized(networkListenerList){
                if (networkListenerList.contains(listener)){
                    networkListenerList.remove(listener)
                }
            }
        }
    }

    /**
     * 当前网络是否可用
     * @return
     */
    @Suppress("DEPRECATION")
    private fun isActive(): Boolean {
        if (connectivityManager == null) {
            return false
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
            val networkCapabilities = connectivityManager?.getNetworkCapabilities(
                connectivityManager?.activeNetwork)
            return (networkCapabilities?.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)?: false)
                    || (networkCapabilities?.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)?: false)
                    || (networkCapabilities?.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)?: false)
        }else{
            val info = connectivityManager?.activeNetworkInfo ?: return false
            return info.isConnected
        }
    }

//    private fun isNetWork():Boolean{
//        LogUtil.i("isNetWork", "CONNECTIVITY_ACTION")
//        return if (connectivityManager == null) {
//          false
//
//        }else{
//            var var3: NetworkInfo?=null
//            if(connectivityManager!!.activeNetworkInfo.also { var3 = it!! } != null) {
//                if (var3!!.isConnected) {
//                    if (var3!!.type == 1) {
//                        LogUtil.d("isNetWork", "当前WiFi连接可用 ")
//                    } else if (var3!!.type == 0) {
//                        LogUtil.d("isNetWork", "当前移动网络连接可用 ")
//                    }
//                   true
//
//                } else {
//                    LogUtil.d("isNetWork", "当前没有网络连接，请确保你已经打开网络 ")
//                     false
//
//                }
//            } else {
//                Log.d("isNetWork", "当前没有网络连接，请确保你已经打开网络 ")
//                false
//
//            }
//        }
//    }

    /**
     * 当前网络是否是wifi
     * @return
     */
    @Suppress("DEPRECATION")
    private fun isWifi(): Boolean {
        return if (!isActive()) {
            false
        } else {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
                val networkCapabilities = connectivityManager?.getNetworkCapabilities(
                    connectivityManager?.activeNetwork)
                networkCapabilities?.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)?: false
            }else{
                connectivityManager?.activeNetworkInfo?.type == ConnectivityManager.TYPE_WIFI
            }
        }
    }
}

/**
 * 网络回调自定义类
 */
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
class CustomNetworkCallback internal constructor(): ConnectivityManager.NetworkCallback() {

    private var lastType = NetworkType.NONE

    override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) {
        super.onCapabilitiesChanged(network, networkCapabilities)
        dispatcherType()
    }

    override fun onLost(network: Network) {
        super.onLost(network)
        dispatcherType()
    }

    private fun dispatcherType(){
        runUI(500L){
            if (NetworkUtil.active()){
                if (NetworkUtil.wifi()){
                    if (lastType != NetworkType.WIFI){
                        lastType = NetworkType.WIFI
                        NetworkUtil.networkListenerList.forEach { it.onChange(lastType) }
                    }
                }else{
                    if (lastType != NetworkType.MOBILE){
                        lastType = NetworkType.MOBILE
                        NetworkUtil.networkListenerList.forEach { it.onChange(lastType) }
                    }
                }
            }else{
                if (lastType != NetworkType.NONE){
                    lastType = NetworkType.NONE
                    NetworkUtil.networkListenerList.forEach { it.onChange(lastType) }
                }
            }
        }
    }

}

/**
 * 网络状态类型
 */
enum class NetworkType{

    /**
     * 没有网
     */
    NONE,

    /**
     * 数据
     */
    MOBILE,

    /**
     * wifi
     */
    WIFI;

}

/**NetworkListener
 * 网络状态监听回调
 */
interface NetworkListener{

    /**
     * 网络发生变化回调
     */
    fun onChange(type: NetworkType)
}